import mx.utils.Delegate;

import gugga.animations.IAnimation;
import gugga.common.EventDescriptor;
import gugga.events.EventDispatcher;
import gugga.utils.Listener;
import gugga.utils.OnEnterFrameBeacon;

/**
 * @author vladimir
 */
class gugga.animations.BlinkingAnimation 
	extends EventDispatcher 
	implements IAnimation 
{
	private var mMovieClip:MovieClip; 
	private var mBlinksCount:Number;
	private var mBlinkFramesDuration:Number = 1;
	
	private var mFramesSinceLastBlink:Number;
	private var mBlinksElapsed:Number;
	private var mInitialVisibility:Boolean;
	
	private var mOnEnterFrameBeaconListener:Listener;
	
	private var mCuePoints : Array;
	
	public function BlinkingAnimation(
		aMovieClip:MovieClip, aBlinksCount:Number, aBlinkFramesDuration:Number) 
	{
		super();
		
		mMovieClip = aMovieClip;
		mBlinksCount = aBlinksCount;
		
		if(aBlinkFramesDuration)
		{
			mBlinkFramesDuration = aBlinkFramesDuration;
		}
		
		mCuePoints = new Array();
	}

	public function addCuePoint(aBlinkNumber:Number, aEventName:String) : Void 
	{
		mCuePoints.push({position: aBlinkNumber, event:aEventName});
		mCuePoints.sortOn("position");
	}

	public function start() : Void 
	{
		if(!isRunning())
		{
			mBlinksElapsed = 0;
			mFramesSinceLastBlink = 0;
			mInitialVisibility = mMovieClip._visible;
			
			dispatchEvent({type: "start", target: this});
			
			if(mBlinksCount > 0)
			{		
				mOnEnterFrameBeaconListener = Listener.create(
					new EventDescriptor(OnEnterFrameBeacon.Instance, "onEnterFrame"), 
					Delegate.create(this, onEnterFrame));
			}
			else
			{
				completed();
			}
		}
	}

	public function isRunning() : Boolean 
	{
		return (mOnEnterFrameBeaconListener != null);
	}

	public function isImmediatelyInterruptable() : Boolean 
	{
		return true;
	}

	public function interrupt() : Void 
	{
		mOnEnterFrameBeaconListener.stop();
		mOnEnterFrameBeaconListener = null;
		mMovieClip._visible = mInitialVisibility;
		
		dispatchEvent({type: "interrupted", target: this});
	}
	
	private function onEnterFrame() : Void 
	{
		// TODO: Implement cue point event dispatching
		mFramesSinceLastBlink++;
		
		if(mFramesSinceLastBlink >= mBlinkFramesDuration)
		{
			mBlinksElapsed++;
			mFramesSinceLastBlink = 0;
		}
		
		if(mBlinksElapsed <= mBlinksCount)
		{	
			mMovieClip._visible = !mMovieClip._visible;
		}
		else
		{
			completed();
		}
	}
	
	private function completed() : Void 
	{
		mOnEnterFrameBeaconListener.stop();
		mOnEnterFrameBeaconListener = null;
		
		dispatchEvent({type:"completed", target:this});
	}
}